﻿@inherits SsoCompontentBase
@implements IDisposable

<MTextField Class="@Class"
            Value="Value"
            ValueChanged="ValueChanged"
            ValueExpression="ValueExpression"
            Outlined Label="@T("SMSCode")"
            Placeholder="@T("SMSCodePlaceholder")"
            Type="number"
            NumberProps="@(prop=> { prop.HideControl = true; })">
    <AppendContent>
        <MButton Style="margin-top:-16px;margin-right:-12px;height:54px;min-width: 120px;"
                 Class="primary rounded-r-lg" Disabled=ActionDisabled OnClick="ClickHandler">
            @ActionContent
        </MButton>
    </AppendContent>
</MTextField>

@code {
    [Parameter]
    public int? Value { get; set; }

    [Parameter]
    public EventCallback<int?> ValueChanged { get; set; }

    [Parameter]
    public Expression<Func<int?>>? ValueExpression { get; set; }

    [Parameter]
    public string Class { get; set; } = string.Empty;

    [Parameter]
    public string Style { get; set; } = string.Empty;

    [Parameter]
    public Func<Task<bool>> OnClick { get; set; } = null!;

    int _counter = 0;
    bool ActionDisabled => _counter > 0;
    string ActionContent => _counter > 0 ? string.Format(T("SmsSendTime"), _counter) : T("GetSmsCode");
    System.Timers.Timer? _timer;

    CancellationTokenSource _cancellationTokenSource = new();

    private async Task ClickHandler()
    {
        if (OnClick == null)
        {
            return;
        }

        _cancellationTokenSource.Cancel();
        _cancellationTokenSource = new CancellationTokenSource();

        try
        {
            await Task.Delay(TimeSpan.FromMilliseconds(500), _cancellationTokenSource.Token);
            var result = await (OnClick.Invoke()).ConfigureAwait(false);
            if (result)
            {
                await InvokeAsync(async () =>
                {
                    await PopupService.EnqueueSnackbarAsync(T("The verification code is sent successfully"), AlertTypes.Success);
                });
                StartCountdownTimer();
            }
        }
        catch (TaskCanceledException)
        {
            // ignore
        }
        catch (Exception e)
        {
            await InvokeAsync(async () =>
            {
                await PopupService.EnqueueSnackbarAsync(e.Message, AlertTypes.Error);
            });
        }
    }

    private void StartCountdownTimer()
    {
        _counter = 60;
        if (_timer is null)
        {
            _timer = new System.Timers.Timer(1000);
            _timer.Elapsed += CountdownTimer;
        }

        _timer.Enabled = true;
    }

    private void CountdownTimer(object? sender, ElapsedEventArgs e)
    {
        if (_counter > 0)
        {
            _counter -= 1;
        }
        else
        {
            _timer!.Enabled = false;
        }

        InvokeAsync(StateHasChanged);
    }

    public void Dispose()
    {
        _cancellationTokenSource?.Dispose();
        _timer?.Dispose();
        _timer = null;
    }
}